﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Solstice
{
    public partial class RenderWindow : Form
    {
        // Form 세팅 관련 변수
        // 위치 및 크기 정보는 이미 RenderWindow를 통해 직접 get/set할 수 있으니 별도로 정의할 필요가 없다고 판단됨
        /*
        public int ScreenWidth;
        public int ScreenHeight;
        public int ScreenX;
        public int ScreenY;
        */

        // 백그라운드 화면 출력 범위

        // 렌더에 필요한 것들
        public Color clearColor = Color.CornflowerBlue;

        // draw 데이터 스트럭쳐
        public struct drawImageStructure
        {
            public Image image;
            public int x;
            public int y;
            public int width;
            public int height;
        }
        public struct drawTextStructure
        {
            public string text;
            public Font font;
        }

        // draw 데이터
        public List<drawImageStructure> drawImage = new List<drawImageStructure>();
        public List<drawTextStructure> drawText = new List<drawTextStructure>();

        /// <summary>
        /// 시작 위치정보가 정의되지 않은 렌더 창을 정의합니다.
        /// </summary>
        public RenderWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 크기 정보가 정의된 렌더 창을 정의합니다.
        /// </summary>
        /// <param name="width">렌더 창의 가로 길이입니다.</param>
        /// <param name="height">렌더 창의 세로 길이입니다.</param>
        public RenderWindow(int width, int height)
        {
            InitializeComponent();
            SetResolution(width, height);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        /// <summary>
        /// 크기 정보와 위치 정보가 정의된 렌더 창을 정의합니다.
        /// </summary>
        /// <param name="width">렌더 창의 가로 길이입니다.</param>
        /// <param name="height">렌더 창의 세로 길이입니다.</param>
        /// <param name="x">렌더 창의 가로 위치입니다. 왼쪽이 0입니다.</param>
        /// <param name="y">렌더 창의 세로 위치입니다. 위쪽이 0입니다.</param>
        public RenderWindow(int width, int height, int x, int y)
        {
            InitializeComponent();
            SetResolution(width, height);
            SetPosition(x, y);
            this.StartPosition = FormStartPosition.Manual;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        /// <summary>
        /// 렌더 창의 위치를 지정합니다.
        /// </summary>
        /// <param name="x">렌더 창의 가로 위치입니다. 왼쪽이 0입니다.</param>
        /// <param name="y">렌더 창의 세로 위치입니다. 위쪽이 0입니다.</param>
        public void SetPosition(int x, int y)
        {
            this.Left = x;
            this.Top = y;
        }

        /// <summary>
        /// 렌더 창의 크기를 지정합니다.
        /// </summary>
        /// <param name="width">렌더 창의 가로 길이입니다.</param>
        /// <param name="height">렌더 창의 세로 길이입니다.</param>
        public void SetResolution(int width, int height)
        {
            this.ClientSize = new Size(width, height);
        }

        /// <summary>
        /// 렌더 창의 제목을 지정합니다.
        /// </summary>
        /// <param name="title">렌더 창의 제목입니다.</param>
        public void SetTitle(string title)
        {
            this.Text = title;
        }

        private void RenderWindow_Paint(object sender, PaintEventArgs e)
        {
            // Pen이나 Brush 등과 같은 GDI+ 리소스는 관리되지 않는 리소스이므로
            // 이 안에서 직접 정의한 리소스는 사용이 끝나는 즉시 Dispose할 것.
            // PaintEventArgs에서 정의한 Graphics는 관리된다고 카더라.

            Graphics g = e.Graphics;
            g.Clear(clearColor);

            foreach (drawImageStructure dis in drawImage)
            {
                g.DrawImage(dis.image, dis.x, dis.y, dis.width, dis.height);
            }
        }

        public void AddRenderItem(drawImageStructure item)
        {
            drawImage.Add(item);
        }

        public int GetRenderItem(drawImageStructure item)
        {
            int r = -1;
            try
            {
                r = drawImage.BinarySearch(item);
            }
            catch (InvalidOperationException e)
            {
                Debug.Print(e.StackTrace);
            }
            return r;
        }

        public void RemoveRenderItem(drawImageStructure item)
        {
            drawImage.Remove(item);
        }

        public void RemoveRenderItem(int index)
        {
            if (index < 0) { return; }
            drawImage.RemoveAt(index);
        }

        private void RenderWindow_Load(object sender, EventArgs e)
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        private void tmrRefresh_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
        }
    }
}
